package com.jlboot.core.plugins.cron4j;

import com.jfinal.kit.StrKit;
import com.jfinal.plugin.IPlugin;
import com.jfinal.plugin.cron4j.ITask;
import it.sauronsoftware.cron4j.Scheduler;
import it.sauronsoftware.cron4j.Task;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by 51594 on 2022/7/28.
 */
@Slf4j
public class MyCron4jPlugin implements IPlugin {

    public static MyCron4jPlugin plugin = null;

    private final List<TaskInfo> taskInfoList = new ArrayList<>();

    public static MyCron4jPlugin getPlugin() {
        if (plugin == null) plugin = new MyCron4jPlugin();
        return plugin;
    }

    /**
     * 手工启动
     *
     * @param taskId
     * @return
     */
    public static boolean startTask(String taskId) {
        for (TaskInfo info : getPlugin().getTaskInfoList()) {
            if (taskId.equals(info.getId())) {
                if (!info.isStatus()) {
                    info.start();
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 任务状态
     *
     * @param taskId
     * @return
     */
    public static boolean getTaskStatus(String taskId) {
        for (TaskInfo info : getPlugin().getTaskInfoList()) {
            if (taskId.equals(info.getId())) {
                return info.isStatus();
            }
        }
        return false;
    }


    /**
     * 任务状态
     *
     * @param taskId
     * @return
     */
    public static boolean hasTask(String taskId) {
        for (TaskInfo info : getPlugin().getTaskInfoList()) {
            if (taskId.equals(info.getId())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 手工启动
     *
     * @param taskId
     * @return
     */
    public static boolean logTask(String taskId, boolean log) {
        for (TaskInfo info : getPlugin().getTaskInfoList()) {
            if (taskId.equals(info.getId())) {
                info.setLog(log);
                return true;
            }
        }
        return false;
    }

    /**
     * 手工ting
     *
     * @param taskId
     * @return
     */
    public static boolean stopTask(String taskId) {
        for (TaskInfo info : getPlugin().getTaskInfoList()) {
            if (taskId.equals(info.getId())) {
                if (info.isStatus()) {
                    info.stop();
                    getPlugin().getTaskInfoList().remove(info);
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * \删除任务
     *
     * @param taskId
     */
    public static void removeTask(String taskId) {
        for (TaskInfo info : getPlugin().getTaskInfoList()) {
            if (taskId.equals(info.getId())) {
                if (info.isStatus()) {
                    getPlugin().getTaskInfoList().remove(info);
                    return;
                }
            }
        }
    }

    /**
     * 手工ting
     *
     * @param taskId
     * @return
     */

    public static void runTask(String taskId) {
        for (TaskInfo info : getPlugin().getTaskInfoList()) {
            if (taskId.equals(info.getId())) {
                info.run();
            }
        }
    }

    /**
     * 取得实例列表
     *
     * @return
     */
    public List<TaskInfo> getTaskInfoList() {
        return taskInfoList;
    }

    public MyCron4jPlugin addTask(String taskId,String taskName, String cron, Object task, boolean daemon, boolean enable, boolean log) {
        TaskInfo info = new TaskInfo(taskId,taskName, cron, task, daemon, enable,log);
        info.setLog(log);
        info.schedule();
        info.start();
        taskInfoList.add(info);
        return this;
    }

    public boolean start() {
        for (TaskInfo taskInfo : taskInfoList) {
            taskInfo.schedule();
        }
        for (TaskInfo taskInfo : taskInfoList) {
            taskInfo.start();
        }
        return true;
    }

    public boolean stop() {
        for (TaskInfo taskInfo : taskInfoList) {
            taskInfo.stop();
        }
        return true;
    }

    public String getTaskId(Class clazz){
        for (TaskInfo taskInfo : MyCron4jPlugin.getPlugin().getTaskInfoList()) {
            if(taskInfo.getTask().getClass().getName().equals(clazz.getName())){
                return taskInfo.getId();
            }
        }
        throw new RuntimeException("找不到任务ID");
    }

    @Data
    public static class TaskInfo {
        Scheduler scheduler;
        //运行中
        boolean status = true;
        String id;
        String name;
        String cron;
        Object task;
        boolean daemon;
        boolean enable;
        boolean log;

        TaskInfo(String id,String name, String cron, Object task, boolean daemon, boolean enable,boolean log) {
            if (StrKit.isBlank(name)) {
                throw new IllegalArgumentException("name 不能为空.");
            }
            if (StrKit.isBlank(cron)) {
                throw new IllegalArgumentException("cron 不能为空.");
            }
            if (task == null) {
                throw new IllegalArgumentException("task 不能为 null.");
            }

            this.id = id.trim();
            this.name = name.trim();
            this.cron = cron.trim();
            this.task = task;
            this.daemon = daemon;
            this.enable = enable;
            this.log = log;
        }

        void schedule() {
            if (enable) {
                scheduler = new Scheduler();
                if (task instanceof Runnable) {
                    scheduler.schedule(cron, (Runnable) task);
                } else if (task instanceof Task) {
                    scheduler.schedule(cron, (Task) task);
                } else {
                    scheduler = null;
                    throw new IllegalStateException("Task 必须是 Runnable、ITask、ProcessTask 或者 Task 类型");
                }
                scheduler.setDaemon(daemon);
            }
        }

        void run() {
            if (enable) {
                if (task instanceof Runnable) {
                    ((Runnable) task).run();
                }
            }
        }

        void start() {
            if (enable) {
                scheduler.start();
                status = true;
            }
        }

        void stop() {
            if (enable) {
                if (task instanceof ITask) {   // 如果任务实现了 ITask 接口，则回调 ITask.stop() 方法
                    ((ITask) task).stop();
                }
                scheduler.stop();
                status = false;
            }
        }
    }

}
